/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package mamayukero.ai.ga;

import mamayukero.problem.environment.Environment;
import mamayukero.problem.environment.component.Machine;
import mamayukero.problem.environment.component.Product;
import mamayukero.problem.environment.component.Vendor;

public class Individual {
    public Chromosome chrom;
    public float fitness;
    public Machine machine;
    public Product product;
    public Vendor vendor;
    
    public Individual() {
        chrom = new Chromosome();
        fitness = fitnessFunction();
    }
    
    public Individual(String allele) {
        chrom = new Chromosome(allele);
        fitness = fitnessFunction();
    }
    
    public Individual(Individual i) {
        this.chrom = i.chrom;
        this.fitness = i.fitness;
    }
    
    public final float fitnessFunction() {
        
        
        int biayaMesin = 0; //biaya mesin
        int totalMesin = 0; //total mesin dari GA terhadap 1 hari
        int prevMesin = 0; //mesin sebelumnya
        int totalKerjaPrevMesin = 0; //total kerja waktu mesin berulang
        int curMesin = 0;
        float hasil = 0;
        
        int produk[] = new int[Environment.typesOfMachine.size()]; //12 harusnya diganti dengan jumlah produk
        int kerjaMesin[] = new int[Environment.typesOfMachine.size()]; //12 harusnya diganti dengan jumlah mesin yang bisa ada
        int istirahat[] = new int[Environment.typesOfMachine.size()]; //12 harusnya diganti jumlah mesin
        
        for (int i = 0; i < Environment.typesOfMachine.size(); i++) {
            produk[i] = 0;
        }
        
        for (int i = 0; i < Environment.typesOfMachine.size(); i++) {
            kerjaMesin[i] = 0;
        }
        
        for (int i = 0; i < Environment.typesOfMachine.size(); i++) {
            istirahat[i] = 0;
        }
        
        String allele = chrom.getAllele();
        
        boolean isFalseSolution = false;
        
        for (int i = 0; i < allele.length() && !isFalseSolution; i++) {
            curMesin = (int)(allele.charAt(i)) - 48;
            
            //jika ada penjadwalan mesin
            if (curMesin != 0) {
                //jika mesin tersebut sudah bekerja pada periode sebelumnya
                if (curMesin == prevMesin) {
                    totalKerjaPrevMesin++;  //lama waktu mesin bekerja tambah 1
                } else {
                    prevMesin = curMesin;
                    totalKerjaPrevMesin = 0;
                }
                
                kerjaMesin[curMesin-1]++;
                
                //jika masih bekerja sesuai dengan waktu yang seharusnya
                if (totalKerjaPrevMesin <= Environment.typesOfMachine.get(curMesin-1).maxPeriod) {//harusnya 3 diisi dengan jam kerja mesin terus menerus
                    if (istirahat[curMesin-1] < Environment.typesOfMachine.get(curMesin-1).restTime && istirahat[curMesin-1] != 0) { //harusnya 1 diisi dengan total waktu istirahat mesin
                        if (Environment.typesOfMachine.get(curMesin-1).dependant > 0) {     //harusnya pengecekan apakah dependen
                            if (produk[Environment.typesOfMachine.get(curMesin-1).dependant-1] >= Environment.typesOfMachine.get(curMesin-1).inputAmount) {
                                produk[Environment.typesOfMachine.get(curMesin-1).dependant-1]-=Environment.typesOfMachine.get(curMesin-1).inputAmount; //harusnya mesin yang didependen
                                produk[curMesin-1]+=(Environment.typesOfMachine.get(curMesin-1).productiv * Environment.typesOfMachine.get(curMesin-1).overloadEffect / 100); //harusnya 20 dan 20/100 total kerugian jika terus menerus dikerjakan
                            } else {
                                //System.out.println("mesin salah dependen = " + curMesin);
                                isFalseSolution = true;
                            }
                        } else {
                            produk[curMesin-1]+=(Environment.typesOfMachine.get(curMesin-1).productiv * Environment.typesOfMachine.get(curMesin-1).overloadEffect / 100); //harusnya 20 dan 20/100 total kerugian jika terus menerus dikerjakan
                        }
                        //untuk waktu istirahat
                        for (int j = 0; j < Environment.typesOfMachine.size(); j++) {
                            if ((curMesin-1) != j)
                                istirahat[j]++;
                        }
                    } else {
                        if (Environment.typesOfMachine.get(curMesin-1).dependant > 0) {     //harusnya pengecekan apakah dependen
                            if (produk[Environment.typesOfMachine.get(curMesin-1).dependant-1] >= Environment.typesOfMachine.get(curMesin-1).inputAmount) {
                                produk[Environment.typesOfMachine.get(curMesin-1).dependant-1]-=Environment.typesOfMachine.get(curMesin-1).inputAmount; //harusnya mesin yang didependen
                                produk[curMesin-1]+=(Environment.typesOfMachine.get(curMesin-1).productiv); //harusnya 20 dan 20/100 total kerugian jika terus menerus dikerjakan
                            } else {
                                //System.out.println("mesin salah dependen = " + curMesin);
                                isFalseSolution = true;
                            }
                        } else {
                            produk[curMesin-1]+=Environment.typesOfMachine.get(curMesin-1).productiv; //harusnya 20 dan 20/100 total kerugian jika terus menerus dikerjakan
                        } 
                        //untuk waktu istirahat
                        for (int j = 0; j < Environment.typesOfMachine.size(); j++) {
                            if ((curMesin-1) == j)
                                istirahat[j] = 0;
                            else
                                istirahat[j]++;
                        }
                    }
                } else {
                    if (Environment.typesOfMachine.get(curMesin-1).dependant > 0) {     //harusnya pengecekan apakah dependen
                        if (produk[Environment.typesOfMachine.get(curMesin-1).dependant-1] >= Environment.typesOfMachine.get(curMesin-1).inputAmount) {
                            produk[Environment.typesOfMachine.get(curMesin-1).dependant-1]-=Environment.typesOfMachine.get(curMesin-1).inputAmount; //harusnya mesin yang didependen
                            produk[curMesin-1]+=(Environment.typesOfMachine.get(curMesin-1).productiv * Environment.typesOfMachine.get(curMesin-1).overloadEffect / 100); //harusnya 20 dan 20/100 total kerugian jika terus menerus dikerjakan
                        } else {
                            //System.out.println("mesin salah dependen = " + curMesin);
                            isFalseSolution = true;
                        }
                    } else {
                        produk[curMesin-1]+=(Environment.typesOfMachine.get(curMesin-1).productiv * Environment.typesOfMachine.get(curMesin-1).overloadEffect / 100); //harusnya 20 dan 20/100 total kerugian jika terus menerus dikerjakan
                    }
                    //untuk waktu istirahat
                    for (int j = 0; j < Environment.typesOfMachine.size(); j++) {
                        if ((curMesin-1) == j)
                            istirahat[j] = 0;
                        else
                            istirahat[j]++;
                    }
                }
                //kerjaMesin[curMesin-1]++;
            } else {
                prevMesin = 0;
                totalKerjaPrevMesin = 0;
            }
            
            totalMesin = 0;
            biayaMesin = 0;
            
        }
        
        totalMesin = 0;
        biayaMesin = 0;
        
        for (int j = 0; j < Environment.typesOfMachine.size(); j++) { //harusnya diisi dengan total mesin
            if (kerjaMesin[j] > 0 && kerjaMesin[j] <= Environment.typesOfMachine.get(j).maxTime) {
                totalMesin++;
                biayaMesin+=Environment.typesOfMachine.get(j).rentPrice; //harusnya diisi dengan biaya sewa suatu mesin
            } else if (kerjaMesin[j] == 0) { 
            } else if (kerjaMesin[j] > Environment.typesOfMachine.get(j).maxTime) {
                //System.out.println("mesin lewat = " + (j+1));
                isFalseSolution = true;
            }

        }
        //System.out.println("harga = "+allele+ " | " + totalMesin+" | "+biayaMesin+" | "+isFalseSolution);
        if (totalMesin > Environment.maxSewaMachine || biayaMesin > Environment.startingMoney) {//harusnya 3 diisi dengan total mesin dalam 1 hari dan 1000000 diisi dengan uang milik Pak Achmad
            isFalseSolution = true;
        } 
        
        if (isFalseSolution) {
            hasil = 0;
        } else {
            for (int i = 0; i < Environment.typesOfMachine.size(); i++) { //harusnya diisi dengan total biaya
                hasil = hasil + (produk[i]* Environment.typesOfProduct.get(i).price); //20 harusnya diisi dengan biaya sebuah produk
            }
            hasil -= biayaMesin;
            
            if (hasil < 0)
                hasil = 0;
        }
        
        //System.out.println("hasil = " + allele + "|" + hasil);
                
        return hasil;
    }
    
    public float getFitness() {
        return fitness;
    }
}
